home *** CD-ROM | disk | FTP | other *** search
- /*
- * $Id: gif.trm,v 1.12.2.3 1999/09/29 13:53:53 lhecking Exp $
- */
-
- /* GNUPLOT -- gif.trm */
-
- /*[
- * Copyright 1998
- *
- * Permission to use, copy, and distribute this software and its
- * documentation for any purpose with or without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.
- *
- * Permission to modify the software is granted, but not the right to
- * distribute the complete modified source code. Modifications are to
- * be distributed as patches to the released version. Permission to
- * distribute binaries produced by compiling modified sources is granted,
- * provided you
- * 1. distribute the corresponding source modifications from the
- * released version in the form of a patch file along with the binaries,
- * 2. add special version identification to distinguish your version
- * in addition to the base release version number,
- * 3. provide your name and address as the primary contact for the
- * support of your modified version, and
- * 4. retain our contact information in regard to use of the base
- * software.
- * Permission to distribute the released version of the source code along
- * with corresponding source modifications in the form of a patch file is
- * granted with same provisions 2 through 4 for binary distributions.
- *
- * This software is provided "as is" without express or implied warranty
- * to the extent permitted by applicable law.
- ]*/
-
- /*
- * This file is included by ../term.c.
- *
- * This terminal driver supports:
- * GD GIF library 1.2 & 1.3
- *
- * To Use:
- *
- * set terminal gif ?options ...?
- *
- * Where an option is:
- *
- * transparent - generate transparent GIFs. The first color will
- * be the transparent one.
- *
- * interlace - generate interlaced GIFs.
- *
- * size (in pixels)
- *
- * font (tiny,small,medium,large,giant)
- *
- * xrrggbb - sets the next color. x is the literal character 'x',
- * rrggbb are the red green and blue components in hex. For example
- * x00ff00 is green. The background color is set first, then the
- * color borders, then the X & Y axis, then the plotting colors.
- * (The wierd color spec is in order to get around limitations
- * in gnuplot's scanner.)
- *
- * This driver is modeled after the PBM driver pbm.trm.
- *
- * AUTHORS
- * Sam Shen <sls@mh1.lbl.gov>
- * Alex Woo <woo@playfair.stanford.edu>
- *
- * CONTRIBUTORS
- * Alfred Reibenschuh <alfred.reibenschuh@it-austria.com> or <fredo@blackbox.at>
- * Ben Laurie <ben@algroup.co.uk>
- *
- * send your comments or suggestions to:
- * info-gnuplot@cs.dartmouth.edu
- *
- * This version outputs either color or monochrome GIFs. The default
- * is 640x480 pixels.
- *
- * link with -Lterm/gd -lgd if your directory structure is gnuplot/term/gd
- *
- * gd is not distributed with gnuplot, because of the UNISYS license thing.
- *
- * find out about gd from http://www.boutell.com/gd/
- *
- * Gd library versions before 1.3, and gd library 1.5 are subject to
- * the Unisys license. Use at your own risk. From version 1.6 on, gd
- * library creates png files instead of gif.
- *
- */
-
- #include "driver.h"
-
- #ifdef TERM_REGISTER
- register_term(gif)
- #endif
-
- #ifdef TERM_PROTO
- TERM_PUBLIC void GIF_options __PROTO((void));
- TERM_PUBLIC void GIF_init __PROTO((void));
- TERM_PUBLIC void GIF_graphics __PROTO((void));
- TERM_PUBLIC void GIF_text __PROTO((void));
- TERM_PUBLIC void GIF_linetype __PROTO((int linetype));
- TERM_PUBLIC void GIF_move __PROTO((unsigned int x, unsigned int y));
- TERM_PUBLIC void GIF_vector __PROTO((unsigned int x, unsigned int y));
- TERM_PUBLIC void GIF_put_text __PROTO((unsigned int x, unsigned int y, char str[]));
- TERM_PUBLIC int GIF_text_angle __PROTO((int ang));
- TERM_PUBLIC void GIF_reset __PROTO((void));
-
- #include "gd.h"
-
- extern gdFontPtr gdFontSmall; /* 6x12 */
- extern gdFontPtr gdFontLarge; /* 8x16 */
- extern gdFontPtr gdFontMediumBold; /* 7x13 */
- extern gdFontPtr gdFontGiant; /* 9x15 */
- extern gdFontPtr gdFontTiny; /* 5x8 */
-
-
- #define GREG_XMAX 640
- #define GREG_YMAX 480
-
-
- static int GIF_XMAX = GREG_XMAX;
- static int GIF_YMAX = GREG_YMAX;
-
-
- #define GIF_FONT_SMALL 1
- #ifdef GIF_FONT_SMALL
- # define gdfont gdFontSmall
- # define GIF_VCHAR 12
- # define GIF_HCHAR 6
- #else
- # define gdfont gdFontMediumBold
- # define GIF_VCHAR 13
- # define GIF_HCHAR 7
- #endif
-
- static gdFontPtr GIF_font;
-
- #define GIF_VTIC (GREG_YMAX/100)
- #define GIF_HTIC (GREG_XMAX/150)
-
- #define GIF_MAX_COLORS 256
- #define GOT_NEXT_PROTO
- #endif
-
- #ifndef TERM_PROTO_ONLY
- #ifdef TERM_BODY
-
- static struct {
- gdImagePtr image;
- gdFontPtr font;
- unsigned int x, y;
- int height;
- int charh, charw;
- int color;
- int n_colors;
- int color_table[GIF_MAX_COLORS];
- int rgb_table[GIF_MAX_COLORS];
- int angle;
- int flags;
- int linetype;
- } gif_state;
-
- #define GIF_USE_TRANSPARENT 1
- #define GIF_USE_INTERLACE 2
-
- /*
- * _options() Called when terminal type is selected.
- * This procedure should parse options on the command line. A list of the
- * currently selected options should be stored in term_options[] in a form
- * suitable for use with the set term command. term_options[] is used by
- * the save command. Use options_null() if no options are available.
- */
- TERM_PUBLIC void
- GIF_options()
- {
- struct value s;
- int gif_font, i;
- char *string;
- unsigned long color;
-
- term_options[0] = NUL;
- gif_state.n_colors = 0;
- gif_state.flags = 0;
- gif_font = 1;
- GIF_font = gdfont;
-
- while (!END_OF_COMMAND) {
- if (almost_equals(c_token, "t$ransparent")) {
- gif_state.flags |= GIF_USE_TRANSPARENT;
- ++c_token;
- } else if (almost_equals(c_token, "i$nterlace")) {
- gif_state.flags |= GIF_USE_INTERLACE;
- ++c_token;
- } else if (almost_equals(c_token, "ti$ny")) {
- GIF_font=gdFontTiny;
- gif_font = 0;
- term->v_char = (unsigned int)(8);
- term->h_char = (unsigned int)(5);
- ++c_token;
- } else if (almost_equals(c_token, "s$mall")) {
- GIF_font = gdFontSmall;
- gif_font = 1;
- term->v_char = (unsigned int) (12);
- term->h_char = (unsigned int) (6);
- ++c_token;
- } else if (almost_equals(c_token, "m$edium")) {
- GIF_font = gdFontMediumBold;
- gif_font = 2;
- term->v_char = (unsigned int) (13);
- term->h_char = (unsigned int) (7);
- ++c_token;
- } else if (almost_equals(c_token, "l$arge")) {
- GIF_font = gdFontLarge;
- gif_font = 3;
- term->v_char = (unsigned int) (16);
- term->h_char = (unsigned int) (8);
- ++c_token;
- } else if (almost_equals(c_token, "l$arge")) {
- GIF_font=gdFontGiant;
- gif_font = 4;
- term->v_char = (unsigned int)(15);
- term->h_char = (unsigned int)(9);
- ++c_token;
- } else if (almost_equals(c_token, "si$ze")) {
- c_token++;
- if (END_OF_COMMAND) {
- GIF_XMAX = GREG_XMAX;
- GIF_YMAX = GREG_YMAX;
- term->v_tic = GIF_YMAX / 80;
- term->h_tic = GIF_XMAX / 80;
- } else {
- GIF_XMAX = real(const_express(&s));
- if (equals(c_token, ",")) {
- c_token++;
- GIF_YMAX = real(const_express(&s));
- term->v_tic = GIF_YMAX / 80;
- term->h_tic = GIF_XMAX / 80;
- term->ymax = GIF_YMAX;
- term->xmax = GIF_XMAX;
- }
- }
- } else { /* not "size" */
- string = input_line + token[c_token].start_index;
- if (sscanf(string, "x%lx", &color) != 1) {
- int_error("invalid color spec, must be xRRGGBB",c_token);
- } else if (gif_state.n_colors == GIF_MAX_COLORS) {
- int_warn("too many colors, ingoring",c_token);
- ++c_token;
- } else {
- gif_state.rgb_table[gif_state.n_colors++] = color;
- ++c_token;
- }
- }
- }
-
-
- /* now generate options string */
-
- if (gif_state.flags & GIF_USE_TRANSPARENT) {
- strcat(term_options, "transparent ");
- }
- if (gif_state.flags & GIF_USE_INTERLACE) {
- strcat(term_options, "interlace ");
- }
- switch (gif_font) {
- case 0:
- strcat(term_options,"tiny ");
- break;
- case 1:
- strcat(term_options, "small ");
- break;
- case 2:
- strcat(term_options, "medium ");
- break;
- case 3:
- strcat(term_options, "large ");
- break;
- case 4:
- strcat(term_options,"giant ");
- break;
- }
- sprintf(term_options + strlen(term_options),
- "size %d,%d ", GIF_XMAX, GIF_YMAX);
-
- for (i = 0; i < gif_state.n_colors; i++) {
- sprintf(term_options + strlen(term_options),
- "x%06x ", gif_state.rgb_table[i]);
- }
- }
-
-
- /*
- * _init() Called once, when the device is first selected. This procedure
- * should set up things that only need to be set once, like handshaking and
- * character sets etc...
- */
- TERM_PUBLIC void
- GIF_init()
- {
- gif_state.linetype = 0;
- }
-
- /*
- * _reset() Called when gnuplot is exited, the output device changed or
- * the terminal type changed. This procedure should reset the device,
- * possibly flushing a buffer somewhere or generating a form feed.
- */
- TERM_PUBLIC void
- GIF_reset()
- {
- }
-
- /*
- * _graphics() Called just before a plot is going to be displayed. This
- * procedure should set the device into graphics mode. Devices which can't
- * be used as terminals (like plotters) will probably be in graphics mode
- * always and therefore won't need this.
- */
- TERM_PUBLIC void
- GIF_graphics()
- {
- int i;
- unsigned int rgb;
- gif_state.font = GIF_font;
- gif_state.color = 0;
- gif_state.image = gdImageCreate((int) (xsize * GIF_XMAX),
- (int) (ysize * GIF_YMAX));
- gif_state.height = (int) (ysize * GIF_YMAX - 1);
- gif_state.charw = term->h_char; /* gif_state.font->w; */
- gif_state.charh = term->v_char; /* gif_state.font->h; */
- for (i = gif_state.n_colors; i < WEB_N_COLORS; i++)
- gif_state.rgb_table[i] =
- (web_color_rgbs[i].r << 16) |
- (web_color_rgbs[i].g << 8) |
- web_color_rgbs[i].b;
- if (gif_state.n_colors < WEB_N_COLORS)
- gif_state.n_colors = WEB_N_COLORS;
- for (i = 0; i < gif_state.n_colors; i++) {
- rgb = gif_state.rgb_table[i];
- gif_state.color_table[i] =
- gdImageColorAllocate(gif_state.image, (rgb >> 16) & 0xff,
- (rgb >> 8) & 0xff, rgb & 0xff);
- }
- if (gif_state.flags & GIF_USE_TRANSPARENT)
- gdImageColorTransparent(gif_state.image,
- gif_state.color_table[0]);
- else
- gdImageColorTransparent(gif_state.image, -1);
- }
-
- /*
- * _text() Called immediately after a plot is displayed. This procedure
- * should set the device back into text mode if it is also a terminal, so
- * that commands can be seen as they're typed. Again, this will probably
- * do nothing if the device can't be used as a terminal.
- */
- TERM_PUBLIC void
- GIF_text()
- {
- if (gif_state.flags & GIF_USE_INTERLACE)
- gdImageInterlace(gif_state.image, 1);
- gdImageGif(gif_state.image, gpoutfile);
- gdImageDestroy(gif_state.image);
- }
-
- /* _move(x,y) Called at the start of a line. The cursor should move to the
- * (x,y) position without drawing.
- */
- TERM_PUBLIC void
- GIF_move(unsigned int x, unsigned int y)
- {
- gif_state.x = x;
- gif_state.y = y;
- }
-
- /* _vector(x,y) Called when a line is to be drawn. This should display a line
- * from the last (x,y) position given by _move() or _vector() to this new (x,y)
- * position.
- */
- TERM_PUBLIC void
- GIF_vector(unsigned int x, unsigned int y)
- {
- int gif_linetype_dotted[5];
-
- if (gif_state.linetype == -1) {
- gif_linetype_dotted[0] = gif_state.color_table[2];
- gif_linetype_dotted[1] = gif_state.color_table[2];
- gif_linetype_dotted[2] = gif_state.color_table[0];
- gif_linetype_dotted[3] = gif_state.color_table[0];
- gif_linetype_dotted[4] = gif_state.color_table[0];
-
- gdImageSetStyle(gif_state.image, gif_linetype_dotted, 5);
- gdImageLine(gif_state.image, gif_state.x, gif_state.height - gif_state.y,
- x, gif_state.height - y, gdStyled);
- } else {
- gdImageLine(gif_state.image, gif_state.x, gif_state.height - gif_state.y,
- x, gif_state.height - y, gif_state.color);
- }
- gif_state.x = x;
- gif_state.y = y;
- }
-
- /* _linetype(lt) Called to set the line type before text is displayed or
- * line(s) plotted. This procedure should select a pen color or line
- * style if the device has these capabilities.
- * lt is an integer from -2 to 0 or greater.
- * An lt of -2 is used for the border of the plot.
- * An lt of -1 is used for the X and Y axes.
- * lt 0 and upwards are used for plots 0 and upwards.
- * If _linetype() is called with lt greater than the available line types,
- * it should map it to one of the available line types.
- * Most drivers provide 9 different linetypes (lt is 0 to 8).
- */
- TERM_PUBLIC void
- GIF_linetype(int type)
- {
- if (type >= (gif_state.n_colors - 3))
- type %= (gif_state.n_colors - 3);
-
- gif_state.color = gif_state.color_table[type + 3];
- gif_state.linetype = type;
- }
-
- /* _put_text(x,y,str) Called to display text at the (x,y) position,
- * while in graphics mode. The text should be vertically (with respect
- * to the text) justified about (x,y). The text is rotated according
- * to _text_angle and then horizontally (with respect to the text)
- * justified according to _justify_text.
- */
- TERM_PUBLIC void
- GIF_put_text(unsigned int x, unsigned int y, char *string)
- {
- if (gif_state.angle == 1) {
- x -= gif_state.charh / 2;
- gdImageStringUp(gif_state.image, gif_state.font,
- x, gif_state.height - y,
- string, gif_state.color);
- } else {
- y += gif_state.charh / 2;
- gdImageString(gif_state.image, gif_state.font,
- x, gif_state.height - y,
- string, gif_state.color);
- }
- }
-
- /* _text_angle(ang) Called to rotate the text angle when placing the y label.
- * If ang = 0 then text is horizontal. If ang = 1 then text is vertically
- * upwards. Returns TRUE if text can be rotated, FALSE otherwise.
- */
- TERM_PUBLIC int
- GIF_text_angle(int ang)
- {
- gif_state.angle = ang;
- return TRUE;
- }
-
- TERM_PUBLIC int
- GIF_set_font(char *fontname)
- {
- char name[32];
- int sep;
- gdFontPtr font;
-
- sep = strcspn(fontname,",");
- strncpy(name,fontname,sep);
- name[sep] = NUL;
-
- if (!strcmp(fontname,"small"))
- font = gdFontSmall;
- else if (!strcmp(fontname,"medium"))
- font = gdFontMediumBold;
- else if(!strcmp(fontname,"large"))
- font = gdFontLarge;
- else if(!strcmp(fontname,"giant"))
- font = gdFontGiant;
- else if(!strcmp(fontname,"tiny"))
- font = gdFontTiny;
- else
- font = GIF_font;
-
- gif_state.charw = font->w;
- gif_state.charh = font->h;
-
- gif_state.font = font;
-
- return TRUE;
- }
-
- #endif /* TERM_BODY */
- #ifdef TERM_TABLE
-
- TERM_TABLE_START(gif_driver)
- "gif", "GIF format [mode] [fontsize] [size] [colors]",
- GREG_XMAX, GREG_YMAX, GIF_VCHAR, GIF_HCHAR,
- GIF_VTIC, GIF_HTIC, GIF_options, GIF_init, GIF_reset,
- GIF_text, null_scale, GIF_graphics, GIF_move, GIF_vector,
- GIF_linetype, GIF_put_text, GIF_text_angle,
- null_justify_text, do_point, do_arrow, GIF_set_font,
- 0, /* pointsize */
- TERM_CAN_MULTIPLOT | TERM_BINARY
- TERM_TABLE_END(gif_driver)
-
- #undef LAST_TERM
- #define LAST_TERM gif_driver
-
- #endif /* TERM_TABLE */
- #endif /* TERM_PROTO_ONLY */
-
- #ifdef TERM_HELP
- START_HELP(gif)
- "1 gif",
- "?commands set terminal gif",
- "?set terminal gif",
- "?set term gif",
- "?terminal gif",
- "?term gif",
- "?gif",
- " The `gif` terminal driver generates output in GIF format. It uses Thomas",
- " Boutell's gd library, which is available from http://www.boutell.com/gd/",
- "",
- " By default, the `gif` terminal driver uses a shared Web-friendy palette."
- "",
- " Syntax:",
- " set terminal gif {transparent} {interlace}",
- " {tiny | small | medium | large | giant}",
- " {size <x>,<y>}",
- " {<color0> <color1> <color2> ...}",
- "",
- " `transparent` instructs the driver to generate transparent GIFs. The first",
- " color will be the transparent one.",
- "",
- " `interlace` instructs the driver to generate interlaced GIFs.",
- "",
- " The choice of fonts is `tiny` (5x8 pixels), `small` (6x12 pixels), `medium`",
- " (7x13 Bold), `large` (8x16) or `giant` (9x15 pixels)",
- "",
- " The size <x,y> is given in pixels---it defaults to 640x480. The number of",
- " pixels can be also modified by scaling with the `set size` command.",
- "",
- " Each color must be of the form 'xrrggbb', where x is the literal character",
- " 'x' and 'rrggbb' are the red, green and blue components in hex. For example,",
- " 'x00ff00' is green. The background color is set first, then the border",
- " colors, then the X & Y axis colors, then the plotting colors. The maximum",
- " number of colors that can be set is 256.",
- "",
- " Examples:",
- " set terminal gif small size 640,480 \\",
- " xffffff x000000 x404040 \\",
- " xff0000 xffa500 x66cdaa xcdb5cd \\",
- " xadd8e6 x0000ff xdda0dd x9500d3 # defaults",
- "",
- " which uses white for the non-transparent background, black for borders, gray",
- " for the axes, and red, orange, medium aquamarine, thistle 3, light blue, blue,",
- " plum and dark violet for eight plotting colors.",
- "",
- " set terminal gif transparent xffffff \\",
- " x000000 x202020 x404040 x606060 \\",
- " x808080 xA0A0A0 xC0C0C0 xE0E0E0 \\",
- " which uses white for the transparent background, black for borders, dark",
- " gray for axes, and a gray-scale for the six plotting colors.",
- "",
- " The page size is 640x480 pixels. The `gif` driver can create either color",
- " or monochromatic output, but you have no control over which is produced.",
- "",
- " The current version of the `gif` driver does not support animated GIFs."
- END_HELP(gif)
- #endif /* TERM_HELP */
-
- /*
- * Local Variables:
- * mode:C
- * End:
- */
-